# 数组遍历
[1, 2, 3].each { |num| puts num * 2 }
# 输出:
# 2
# 4
# 6

# 哈希遍历
{ a: 1, b: 2 }.each { |key, value| puts "#{key}: #{value}" }
# 输出:
# a: 1
# b: 2

puts "==========================================="

# each_with_index - 带索引的遍历
%w[a b c].each_with_index do |item, index|
  puts "#{index}: #{item}"
end
# 输出:
# 0: a
# 1: b
# 2: c

puts "==========================================="

# map/collect - 转换集合
squares = [1, 2, 3].map { |n| n ** 2 }
p squares # [1, 4, 9]

upcased = %w[ruby python].map(&:upcase)
p upcased # ["RUBY", "PYTHON"]

puts "==========================================="

# select/find_all - 筛选元素
evens = (1..10).select { |n| n.even? }
p evens # [2, 4, 6, 8, 10]

puts "==========================================="

# reject - 排除元素
odds = (1..10).reject(&:even?)
p odds # [1, 3, 5, 7, 9]

puts "==========================================="

# `find`/`detect` - 查找单个元素
first_even = [1, 3, 5, 6, 7].find(&:even?)
p first_even # 6

puts "==========================================="

# any? - 检查任意元素满足条件
has_even = [1, 3, 5, 7].any?(&:even?)
p has_even # false

puts "==========================================="

# all? - 检查所有元素满足条件
all_positive = [1, 2, 3].all? { |n| n > 0 }
p all_positive # true

puts "==========================================="

# `reduce`/`inject` - 累积计算
sum = [1, 2, 3].reduce(0) { |total, n| total + n }
p sum # 6

product = [1, 2, 3, 4].inject(:*)
p product # 24

puts "==========================================="

# group_by - 分组
grouped = %w[apple banana orange].group_by { |word| word.length }
p grouped
# {5=>["apple"], 6=>["banana", "orange"]}

puts "==========================================="

# `step` - 步进迭代
(1..10).step(2) { |n| puts n }
# 输出:
# 1
# 3
# 5
# 7
# 9

puts "==========================================="

# cycle - 循环迭代
count = 0
[1, 2, 3].cycle(2) do |n|
  puts n
  count += 1
  break if count >= 5
end
# 输出:
# 1
# 2
# 3
# 1
# 2

puts "==========================================="

# 基本自定义迭代器
class MyCollection
  def initialize(data)
    @data = data
  end

  def my_each
    index = 0
    while index < @data.length
      yield @data[index]
      index += 1
    end
  end
end

collection = MyCollection.new([10, 20, 30])
collection.my_each { |n| puts n * 2 }
# 输出:
# 20
# 40
# 60

puts "==========================================="

# 带枚举器的实现
class MyRange
  def initialize(start, stop)
    @start = start
    @stop = stop
  end

  def each
    return enum_for(:each) unless block_given?

    current = @start
    while current <= @stop
      yield current
      current += 1
    end
  end
end

range = MyRange.new(1, 3)
range.each { |n| puts n }
# 输出:
# 1
# 2
# 3

# 可以转换为数组
p range.each.to_a # [1, 2, 3]

puts "==========================================="

# 迭代器链式调用
result = (1..100)
           .select { |n| n % 3 == 0 }    # 3的倍数
           .reject { |n| n % 5 == 0 }     # 排除5的倍数
           .map { |n| n * 2 }             # 每个元素乘以2
           .take(5)                       # 取前5个

p result # [6, 12, 18, 24, 36]

puts "==========================================="

# **惰性求值**：使用`lazy`处理大数据集
large_data = (1..Float::INFINITY).lazy
                                 .select(&:even?)
                                 .map { |x| x * x }
                                 .take(5)
                                 .to_a

p large_data # [4, 16, 36, 64, 100]

